#include "net/TCPServer.h"
#include "eventloop/Eventloop.h"
#include "net/Sockaddr.h"
#include "utility/chrono.h"
#include "net/Buffer.h"
#include "net/TcpConnection.h"

#include <memory>
#include <functional>
#include <string>
#include <stdio.h>
#include <unistd.h>
using namespace std;
using namespace std::placeholders;
using namespace Utility;

class TestServer
{
 public:
  TestServer(Eventloop* loop,
             const Sockaddr& listenAddr)
    : loop_(loop),
      server_(*loop, listenAddr, "TestServer")
  {
    server_.set_connection_callback(
        std::bind(&TestServer::onConnection, this, _1));
    server_.set_message_callback(
        std::bind(&TestServer::onMessage, this, _1, _2, _3));

    message1_.resize(100);
    message2_.resize(200);
    std::fill(message1_.begin(), message1_.end(), 'A');
    std::fill(message2_.begin(), message2_.end(), 'B');
  }

  void start()
  {
	  server_.start();
  }

 private:
  void onConnection(const TCPConnectionPtr& conn)
  {
    if (conn->is_connected())
    {
      printf("onConnection(): new connection [%s] from %s\n",
             conn->name().c_str(),
             conn->peer().IP_port().c_str());
      conn->send(message1_);
      conn->send(message2_);
      conn->shutdown();
    }
    else
    {
      printf("onConnection(): connection [%s] is down\n",
             conn->name().c_str());
    }
  }

  void onMessage(const TCPConnectionPtr& conn,
                 Buffer &buf,
                 timepoint receiveTime)
  {
    string msg(buf.retrieve_as_string());
	printf("onMessage(): received %zd bytes from connection [%s] at %s\n",
           msg.size(),
           conn->name().c_str(),
           to_string(receiveTime).c_str());

    conn->send(msg);
  }

  Eventloop* loop_;
  TCPServer server_;

  string message1_;
  string message2_;
};


int main()
{
  printf("main(): pid = %d\n", getpid());

  Sockaddr listenAddr(8888);
  Eventloop loop;

  TestServer server(&loop, listenAddr);
  server.start();

  loop.loop();
}